package com.wondersgroup.restbase.dao;

import java.io.Serializable;
import java.util.List;

/**
 * 数据访问对象的公共接口
 * @author wondersgroup
 *
 * @param <T> 业务实体类型
 */
public interface BaseDao<T>
{
    /**
     * 加载所有或分页加载业务数据的接口
     * @param startNoAndSize 可变参数startNo和size，startNo为起始记录，size为加载的个数
     * @return 业务实体集合
     */
    public List<T> getAll(final int... startNoAndSize);

    /**
     * 根据主键加载业务数据的方法
     * @param id 业务主键
     * @return 业务实体
     */
    public T findById(Serializable id);

    /**
     * 保存或更新业务实体的方法
     * @param object 业务实体
     * @return 已经保存或更新的业务实体
     */
    public T save(T object);

    /**
     * 删除业务数据的方法
     * @param id 业务主键
     */
    public void remove(Serializable id);

    /**
     * 根据查询语句与预编译参数获取查询结果个数的方法
     * @param sql 查询语句
     * @param values 预编译可变参数
     * @return 该查询结果的个数
     */
    public long getCount(final String sql, final Object... values);
    
    /**
     * 根据业务主键判断对应的业务数据是否存在
     * @param id 业务主键
     * @return 判定结果的布尔值
     */
    public boolean exists(Serializable id);

    /**
     * 根据业务实体的属性值加载符合条件的实体集合
     * @param 实体属性名
     * @param 实体属性值
     * @param 可变参数startNo和size，startNo为起始记录，size为加载的个数
     * @return 符合条件的实体集合
     */
    public List<T> findByProperty(final String propertyName,
                                  final Object value, final int... startNoAndSize);

    /**
     * 通过模糊匹配实体属性值的条件加载实体集合
     * @param propertyName 实体属性名
     * @param value 实体属性值 
     * @param startNoAndSize 可变参数startNo和size，startNo为起始记录，size为加载的个数 
     * @return 模糊匹配的实体集合
     */
    public List<T> findLikeProperty(final String propertyName,
                                    final Object value, final int... startNoAndSize);
    
    /**
     * 根据唯一属性加载单条业务数据的方法
     * @param 实体属性名
     * @param 实体属性值
     * @return 业务实体
     */
    public T findUniqueByProperty(final String propertyName, final Object value);

    /**
     * 通过查询语句加载业务实体集合的方法
     * @param sql 查询语句
     * @param values 预编译可变参数
     * @return 查询结果的实体集合
     */
    public List<T> findAllByQuery(final String sql, final Object... values);

    /**
     * 通过查询语句和分页条件加载业务实体集合的方法
     * @param sql 查询语句
     * @param values 预编译参数数组
     * @param startNoAndSize 可变参数startNo和size，startNo为起始记录，size为加载的个数
     * @return 查询结果的实体集合
     */
    public List<T> findByQuery(String sql, Object[] values, int... startNoAndSize);

    /**
     * 通过查询语句获取唯一结果的方法
     * @param sql 查询语句
     * @param values 预编译可变参数
     * @return 唯一查询结果
     */
    public T findUniqueByQuery(final String sql, final Object... values);
    
    /**
     * 通过查询语句和预编译参数更新业务数据的方法
     * @param sql 查询语句
     * @param values 预编译可变参数
     * @return 影响记录数
     */
    public int executeUpdate(String sql, Object... values);
    
    /**
     * 批量保存业务数据的方法
     * @param list 业务实体集合
     * @return 已吃就好的业务实体集合
     */
    public List<T> save(List<T> list);
}
